#pragma once
#include "Json.hpp"
#include <set>
#include <QVector>
#include <QPair>
#include <QMap>
#include <QSet>
#include <QString>
#include <QPoint>
#include <QPointF>
#include <QColor>
#include <QSize>
#include <QRect>
#include <QDate>
inline bool operator<(const QPoint& a, const QPoint& b) {
    if (a.y() == b.y()) {
        return a.x() < b.x();
    }
    return a.y() < b.y();
}
inline bool operator<(const QPointF& a, const QPointF& b) {
    if (a.y() == b.y()) {
        return a.x() < b.x();
    }
    return a.y() < b.y();
}

template <>
class JsonParser<QString>
{
public:
    bool empty(const QString& value) const {return value.isEmpty();}

    bool from_key(const std::string& key, QString& value) const {
        value = QString::fromStdString(key);
        return true;
    }
    bool to_key(const QString& value, std::string& key) const {
        key = value.toStdString();
        return true;
    }
};

template <typename E>
class JsonParser<QSet<E>>
{
public:
    bool empty(const QSet<E>& value) const {return value.empty();}

    bool write(rapidjson::Document::AllocatorType& allocator, rapidjson::Value& doc, const QSet<E>& value) const {
        //由于QSet数据是无序的，转为 std::set 存储
        return JsonParser<std::set<E>>().write(allocator, doc, std::set<E>(value.begin(), value.end()));
    }
};

template <typename E>
class JsonParser<QVector<E>>
{
public:
    bool empty(const QVector<E>& value) const {return value.empty();}

    bool write(rapidjson::Document::AllocatorType& allocator, rapidjson::Value& doc, const QVector<E>& value) const {
        doc.SetArray();
        auto parser = JsonParser<E>();
        for (auto& e : value) {
            rapidjson::Value temp;
            parser.write(temp, allocator, e);
            doc.PushBack(temp, allocator);
        }
        return true;
    }
};

template <typename K, typename V>
class JsonParser<QMap<K, V>>
{
public:
    bool empty(const QMap<K, V>& value) const {return value.empty();}
};

template <>
class JsonParser<QColor>
{
public:
    bool empty(const QColor& value) const {return !value.isValid();}
};

template <>
class JsonParser<QPoint>
{
public:
    bool empty(const QPoint& value) const {return value.isNull();}

    bool from_key(const std::string& key, QPoint& value) const {
        return false;
    }
    bool to_key(const QPoint& value, std::string& key) const {
        return false;
    }
};

template <>
class JsonParser<QPointF>
{
public:
    bool empty(const QPointF& value) const {return value.isNull();}

    bool from_key(const std::string& key, QPoint& value) const {
        return false;
    }
    bool to_key(const QPoint& value, std::string& key) const {

        return false;
    }
};

template <>
class JsonParser<QSize>
{
public:
    bool empty(const QSize& value) const {return value.isNull();}
};

template <>
class JsonParser<QRect>
{
public:
    bool empty(const QRect& value) const {return value.isNull();}
};

template <>
class JsonParser<QMargins>
{
public:
    bool empty(const QMargins& value) const {return value.isNull();}
};

template <>
class JsonParser<QDate>
{
public:
    bool empty(const QDate& value) const {return value.isNull();}
};

template <>
class JsonParser<QTime>
{
public:
    bool empty(const QTime& value) const {return value.isNull();}
};

template <>
class JsonParser<QDateTime>
{
public:
    bool empty(const QDateTime& value) const {return value.isNull();}
};
